package com.alks.function.service.impl;

import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.utils.DateUtils;
import com.alks.common.utils.beanutils.ObjectUtils;
import com.alks.common.utils.excelUtils.CellStyleBuild;
import com.alks.common.utils.excelUtils.ExcelPoiUtils;
import com.alks.common.utils.excelUtils.ExcelUtils;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.entity.exception.ServiceErrorException;
import com.alks.function.data.dto.*;
import com.alks.function.data.request.FormingFeedingRequest;
import com.alks.function.data.request.FormingProductionRequest;
import com.alks.function.mapper.FormingProductionMapper;
import com.alks.function.service.FormingProductionService;
import com.alks.function.service.async.FileExportAsyncService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;

@Service
@Slf4j
public class FormingProductionServiceImpl implements FormingProductionService {

    @Autowired
    private FormingProductionMapper formingProductionMapper;
    @Autowired
    private FileExportAsyncService fileExportAsyncService;

    /**
     * 查询指令投产量
     * @param request
     * @return
     */
    @Override
    public ResponseInfo getStyleDetail(FormingProductionRequest request) {
        Map map=new HashMap();

        if (request.getPageNum() == null || request.getPageSize() == null) {
            request.setPageNum(1);
            request.setPageSize(10);
        }
        PageHelper.startPage(request.getPageNum(), request.getPageSize());

        String companyId = UserIdThread.get().getCompanyId();
        //查询指令投产量
        List<FormingProductionDto> details = formingProductionMapper.getStyleDetails(request.getLotNo(), request.getStyle(),companyId);

        //封装结果
        PageInfo list=new PageInfo(details);

        //查询投产量总数
        PcLotHeadCountDto count = formingProductionMapper.getCount(request.getLotNo(), request.getStyle(),companyId);

        map.put("details", details);
        map.put("total", list.getTotal());
        map.put("count", count);

        return ResponseInfo.ok(map);
    }

    /**
     * 号码明细
     * @param lotNo
     * @return
     */
    @Override
    public ResponseInfo getNumberDetail(String lotNo) {
        Map map=new HashMap();

        String companyId = UserIdThread.get().getCompanyId();
        //查询号码明细
        List<FormingProductionNumDto> numberDetails = formingProductionMapper.getNumberDetails(lotNo,companyId);

        //查询号码明细总数
        FormingProductionCountDto count = formingProductionMapper.getNumberDetailsCount(lotNo,companyId);

        map.put("numberDetails", numberDetails);
        map.put("count", count);

        return ResponseInfo.ok(map);
    }

    /**
     * 指令投料明细
     * @param lotNo
     * @return
     */
    @Override
    public ResponseInfo getThrowDetail(String lotNo) {

        Map map = new HashMap<>();
        String companyId = UserIdThread.get().getCompanyId();
        //指令投料明细
        List<PcLastCollectDetailDto> details = formingProductionMapper.getThrowDetails2(lotNo,companyId);

        //指令投料明细总数
        Integer count = formingProductionMapper.getThrowCount(lotNo,companyId);

        map.put("ThrowDetails",details);
        map.put("ThrowCount",count);

        return ResponseInfo.ok(map);
    }

    /**
     * 指令产量明细
     * @param lotNo
     * @return
     */
    @Override
    public ResponseInfo getProductionDetail(String lotNo) {
        Map map = new HashMap<>();

        String companyId = UserIdThread.get().getCompanyId();
        //指令投料明细
        List<PcLastCollectDetailDto> details = formingProductionMapper.getProductionDetails2(lotNo,companyId);

        //指令投料明细总数
        Integer count = formingProductionMapper.getProductionCount(lotNo,companyId);

        map.put("ProductionDetails",details);
        map.put("ProductionCount",count);

        return ResponseInfo.ok(map);
    }

    /**
     * 查询线别
     * @return
     */
    @Override
    public ResponseInfo getLines() {
        return ResponseInfo.ok(formingProductionMapper.getLineDetails(UserIdThread.get().getCompanyId()));
    }

    /**
     * 成型投料查询
     * @param request
     * @return
     */
    @Override
    public ResponseInfo getFeedingDetails(FormingFeedingRequest request) {

        Map map = new HashMap<>();

        if (request.getPageNum() == null || request.getPageSize() == null) {
            request.setPageNum(1);
            request.setPageSize(10);
        }
        PageHelper.startPage(request.getPageNum(), request.getPageSize());

        String companyId = UserIdThread.get().getCompanyId();
        request.setCompanyId(companyId);
        //成型投料明细
        List<FormingFeedingDto> feedingDetails = formingProductionMapper.getFormingFeedingDetails(request);
        //封装结果
        PageInfo feedingDetailsList=new PageInfo(feedingDetails);

        //成型今日投料总数
        BigDecimal todayFeedingCount = formingProductionMapper.getFeedingDetailsCount(request);

        for (FormingFeedingDto feedingDetail : feedingDetails) {
            //查询订单数量
            BigDecimal orderNumCount = formingProductionMapper.getOrderNumCount(feedingDetail.getLotNo(),companyId);
            feedingDetail.setOrderNumCount(orderNumCount);

            //查询每个指令投料生产明细
            List<PcLastCollectDetailDto> throwDetails = formingProductionMapper.getThrowDetails(feedingDetail.getLotNo(), companyId);

            //初始值
            extracted(throwDetails, feedingDetail);

            BigDecimal orderNumCount2 = feedingDetail.getOrderNumCount() != null ? feedingDetail.getOrderNumCount() : BigDecimal.ZERO;
            BigDecimal accumulate = feedingDetail.getAccumulate() != null ? feedingDetail.getAccumulate() : BigDecimal.ZERO;
            //未投数量
            BigDecimal submittedNotNumCount = orderNumCount2.subtract(accumulate);
            feedingDetail.setSubmittedNotNumCount(submittedNotNumCount);
        }

        map.put("feedingDetails",feedingDetailsList);
        map.put("todayFeedingCount",todayFeedingCount);

        return ResponseInfo.ok(map);
    }

    /**
     * 查询成型产料产出明细
     * @param request
     * @return
     */
    @Override
    public ResponseInfo getOutputDetails(FormingFeedingRequest request) {
        Map map = new HashMap<>();

        if (request.getPageNum() == null || request.getPageSize() == null) {
            request.setPageNum(1);
            request.setPageSize(10);
        }
        //查询成型产出明细
        request.setPageIndex(request.getPageNum() - 1);
        String companyId = UserIdThread.get().getCompanyId();
        request.setCompanyId(companyId);
        List<FormingFeedingDto> OutputDetails = formingProductionMapper.getFormingOutputDetails(request);

        //封装结果
        PageInfo OutputDetailsList=new PageInfo(OutputDetails);
        OutputDetailsList.setTotal(formingProductionMapper.getFormingOutputDetailsCount(request));

        //统计成型当日产出数量
        BigDecimal todayOutputCount = formingProductionMapper.getOutputDetailsCount(request);

        for (FormingFeedingDto outputDetail : OutputDetails) {
            //查询订单数量
            BigDecimal orderNumCount = formingProductionMapper.getOrderNumCount(outputDetail.getLotNo(), companyId);
            outputDetail.setOrderNumCount(orderNumCount);

            //查询每个指令下产料产出明细
            List<PcLastCollectDetailDto> productionDetails = formingProductionMapper.getProductionDetails(outputDetail.getLotNo(), companyId);

            extracted(productionDetails, outputDetail);

            BigDecimal orderNumCount2 = outputDetail.getOrderNumCount() != null ? outputDetail.getOrderNumCount() : BigDecimal.ZERO;
            BigDecimal accumulate = outputDetail.getAccumulate() != null ? outputDetail.getAccumulate() : BigDecimal.ZERO;
            //未产数量
            BigDecimal submittedNotNumCount = orderNumCount2.subtract(accumulate);
            outputDetail.setSubmittedNotNumCount(submittedNotNumCount);
        }
        map.put("OutputDetailsList",OutputDetailsList);
        map.put("todayOutputCount",todayOutputCount);

        return ResponseInfo.ok(map);
    }

    /**
     * 累计方法抽取
     * @param Details
     * @param dto
     */
    private void extracted(List<PcLastCollectDetailDto> Details, FormingFeedingDto dto) {
        //初始值
        BigDecimal accumulate = BigDecimal.ZERO;
        for (PcLastCollectDetailDto productionDetail : Details) {
            //根据日期遍历累计求和
            if (productionDetail.getCollectTime().compareTo(dto.getCollectTime()) <= 0) {
                accumulate = accumulate.add(productionDetail.getQty());
                dto.setAccumulate(accumulate);
            }
        }
    }

    /**
     * 成型-导出日报表
     * @param request
     */
    @Override
    public void exportDailyReport(FormingFeedingRequest request , HttpServletResponse response) {
        if (ObjectUtils.isEmpty(request.getStartTime())){
            throw new ServiceErrorException("日期不可为空!");
        }
        String companyId = UserIdThread.get().getCompanyId();
        List<FormingFeedingDayDto> dtoList = formingProductionMapper.exportDailyReport(request.getStartTime(), companyId);

        List<List<String>> dateList = new ArrayList<>();
//        List<String> headList = new ArrayList<>();
//        headList.addAll(Arrays.asList("部门", "品牌", "款号", "季节", "指令", "型体", "颜色", "颜色代码", "订单数量", "当日投产", "累计投产", "投料欠数", "当日产出", "累计产出", "产出欠数"));
//        dateList.add(headList);


        // 使用 LinkedHashMap 存储按 Line 分组的数据，保持插入顺序
        Map<String, List<FormingFeedingDayDto>> map = new LinkedHashMap<>();
        for (FormingFeedingDayDto dto : dtoList) {
            map.computeIfAbsent(dto.getLine(), k -> new ArrayList<>()).add(dto);
        }

        for (Map.Entry<String, List<FormingFeedingDayDto>> entry : map.entrySet()) {
            String line = entry.getKey();
            List<FormingFeedingDayDto> lineDtos = entry.getValue();

            int count1 = 0;
            int count2 = 0;
            int count3 = 0;
            int count4 = 0;

            for (FormingFeedingDayDto dto : lineDtos) {
                // 普通数据
                List<String> bodyList = new ArrayList<>();
                bodyList.add(dto.getLine());
                bodyList.add(dto.getCustom());
                bodyList.add(dto.getStyleName());
                bodyList.add(dto.getSeason());
                bodyList.add(dto.getLotNo());
                bodyList.add(dto.getStyle());
                bodyList.add(dto.getColor());
                bodyList.add(dto.getColorCode());
                bodyList.add(dto.getOrderQty().toString());
                bodyList.add(dto.getDayIn().toString());
                bodyList.add(dto.getAccumulate().toString());
                bodyList.add(dto.getSubmittedOwingAmount().toString());
                bodyList.add(dto.getDayOut().toString());
                bodyList.add(dto.getAccumulate2().toString());
                bodyList.add(dto.getProducedOwingAmount().toString());

                // 计算总计数据
                count1 += dto.getDayIn();
                count2 += dto.getAccumulate();
                count3 += dto.getDayOut();
                count4 += dto.getAccumulate2();

                dateList.add(bodyList);
            }

            // 当前线别的总计数据
            List<String> countList = new ArrayList<>();
            countList.addAll(Arrays.asList("", "", "", "", "", "", "", "", "合计:", String.valueOf(count1), String.valueOf(count2), "", String.valueOf(count3), String.valueOf(count4), ""));
            dateList.add(countList);
        }

        // 打印 dateList 中的所有数据
        for (List<String> row : dateList) {
            // 定义每列的宽度
            String format = "%-8s%-8s%-12s%-8s%-12s%-8s%-12s%-8s%-10s%-10s%-10s%-10s%-10s%-10s%-10s";
            System.out.println(String.format(format, row.toArray()));
        }

        String fileName = "成型日报表" + DateUtils.dateTimeNow() +".xls";
        //获取模板
        TemplateExportParams templateParams = new TemplateExportParams("templates/成型日报表模板.xls");
        //开启横向遍历 开启横向遍历 开启横向遍历
        templateParams.setColForEach(true);
        //字体样式
        CellStyleBuild cellStyle = new CellStyleBuild();
        cellStyle.setFontName("宋体");
        cellStyle.setFontSize((short) 12);
        ArrayList<Integer> headerRowIndexList = new ArrayList<>();
        HashMap<String, Object> map1 = new HashMap<>();
        map1.put("date",request.getStartTime());

        try{
            ExcelUtils.setResponseZF(response, fileName);
            ExcelPoiUtils.writeExcelList222(response, map1, dateList,
                    templateParams,
                    3, 0,16,headerRowIndexList,
                    cellStyle,cellStyle,false,null);
        } catch (Exception e) {
            log.error("成型日报表导出失败, 错误信息: {}", e.getMessage());
            throw new ServiceErrorException(e.getMessage());
        }
    }

    /**
     * 导出月报表
     * @param request
     * @param response
     */
    @Override
    public void exportMonthlyReport(FormingFeedingRequest request, HttpServletResponse response) {
        if (ObjectUtils.isEmpty(request.getStartTime())){
            throw new ServiceErrorException("日期不可为空!");
        }

        fileExportAsyncService.doExport(request, UserIdThread.get());
    }

}
